home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / swtools / libdwarf / dwarf_frame.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  46.2 KB  |  1,471 lines

  1. /*
  2.     dwarf_frame.c
  3.  
  4.     This file implements the API relating to frames
  5.     contained in the debug_frame section.
  6.  
  7.     $Revision: 1.36 $ $Date: 1994/07/05 21:59:37 $
  8. */
  9.  
  10.  
  11. #include <stdio.h>
  12. #include "dwarf_incl.h"
  13. #include "dwarf_frame.h"
  14. #include "dwarf_arange.h" /* using Arange as a way to build a list*/
  15.  
  16.  
  17. /* 
  18.     This function is the heart of the debug_frame stuff.  Don't even
  19.     think of reading this without reading both the Libdwarf and 
  20.     consumer API carefully first.  This function basically executes     
  21.     frame instructions contained in a Cie or an Fde, but does in a      
  22.     number of different ways depending on the information sought.       
  23.     Start_instr_ptr points to the first byte of the frame instruction    
  24.     stream, and final_instr_ptr to the to the first byte after the       
  25.     last.                                                                
  26.                                                                         
  27.     The offsets returned in the frame instructions are factored.  That   
  28.     is they need to be multiplied by either the code_alignment_factor    
  29.     or the data_alignment_factor, as appropriate to obtain the actual      
  30.     offset.  This makes it possible to expand an instruction stream      
  31.     without the corresponding Cie.  However, when an Fde frame instr     
  32.     sequence is being expanded there must be a valid Cie with a pointer  
  33.     to an initial table row.                                             
  34.                                                                          
  35.     If unsuccessful (there is an error) this function 
  36.     returns a negative number (an error code).
  37.     If successful and make_instr is false it returns 1.  
  38.     If successful and make_instr is true,
  39.         it returns the number of frame instructions executed. 
  40.     It does not do a whole lot of input validation being a private 
  41.     function.  Please make sure inputs are valid.
  42.                                                                         
  43.     (1) If make_instr is true, it makes a list of pointers to              
  44.     Dwarf_Frame_Op structures containing the frame instructions          
  45.     executed.  A pointer to this list is returned in ret_frame_instr.    
  46.     Make_instr is true only when a list of frame instructions is to be   
  47.     returned.  In this case since we are not interested in the contents  
  48.     of the table, the input Cie can be NULL.  This is the only case
  49.     where the inpute Cie can be NULL.
  50.  
  51.     (2) If search_pc is true, frame instructions are executed till       
  52.     either a location is reached that is greater than the search_pc_val
  53.     provided, or all instructions are executed.  At this point the       
  54.     last row of the table generated is returned in a structure.          
  55.     A pointer to this structure is supplied in table.                    
  56.                                                                     
  57.     (3) This function is also used to create the initial table row       
  58.     defined by a Cie.  In this case, the Dwarf_Cie pointer cie, is       
  59.     NULL.  For an FDE, however, cie points to the associated Cie.        
  60. */
  61. static Dwarf_Sword
  62. _dwarf_exec_frame_instr (
  63.     Dwarf_Bool      make_instr,         /* Make list of frame instr?        */
  64.     Dwarf_Frame_Op  **ret_frame_instr,  /* Ptr to list of ptrs to fr instrs */
  65.     Dwarf_Bool      search_pc,          /* Search for a pc value?           */
  66.     Dwarf_Addr      search_pc_val,      /* Search for this pc value         */
  67.     Dwarf_Addr         loc,        /* initial location value         */
  68.     Dwarf_Small     *start_instr_ptr,   /* Ptr to start of frame instrs.    */
  69.     Dwarf_Small     *final_instr_ptr,   /* Ptr just past frame instrs.      */
  70.     Dwarf_Frame     table,              /* Ptr to struct with last row.     */
  71.     Dwarf_Cie       cie,                /* Ptr to Cie used by the Fde.      */
  72.     Dwarf_Debug     dbg                 /* Associated Dwarf_Debug           */
  73. )
  74. {
  75.     /* Sweeps the frame instructions. */
  76.     Dwarf_Small     *instr_ptr;
  77.  
  78.     /* Obvious from the documents. */
  79.     Dwarf_Small     instr, opcode;
  80.     Dwarf_Small     reg_no, reg_noA, reg_noB;
  81.     Dwarf_Unsigned  factored_N_value;
  82.     Dwarf_Addr      new_loc;
  83.     Dwarf_Unsigned  adv_loc;
  84.  
  85.     struct Dwarf_Reg_Rule_s       reg[DW_FRAME_LAST_REG_NUM];
  86.  
  87.     /* This is used to end executing frame instructions.    */
  88.     /* Becomes true when search_pc is true and loc          */
  89.     /* is greater than search_pc_val.                       */
  90.     Dwarf_Bool              search_over = false;
  91.  
  92.     /* Used by the DW_FRAME_advance_loc instr   */
  93.     /* to hold the increment in pc value.       */
  94.     Dwarf_Addr              adv_pc;
  95.  
  96.     /* Contains the length in bytes of  */
  97.     /* an leb128 encoded number.        */
  98.     Dwarf_Word              leb128_length;
  99.  
  100.     /* Counts the number of frame instructions executed.    */
  101.     Dwarf_Word          instr_count = 0;
  102.  
  103.     /* 
  104.        These contain the current fields     
  105.        of the current frame instruction.    
  106.     */
  107.     Dwarf_Small     fp_base_op = 0;
  108.     Dwarf_Small     fp_extended_op;
  109.     Dwarf_Half      fp_register;
  110.     Dwarf_Unsigned  fp_offset;
  111.     Dwarf_Off       fp_instr_offset;
  112.  
  113.     /*
  114.         Stack_table points to the row (Dwarf_Frame ie) being
  115.         pushed or popped by a remember or restore instruction.
  116.         Top_stack points to the top of the stack of rows.
  117.     */
  118.     Dwarf_Frame       stack_table;
  119.     Dwarf_Frame       top_stack = NULL;
  120.  
  121.     /* 
  122.        These are used only when make_instr is true.         
  123.        Curr_instr is a pointer to the current frame         
  124.        instruction executed.  Curr_instr_ptr,               
  125.        head_instr_list, and curr_instr_list are used        
  126.        to form a chain of Dwarf_Frame_Op structs.           
  127.        Dealloc_instr_ptr is used to deallocate the          
  128.        structs used to form the chain.  Head_instr_block    
  129.        points to a contiguous list of pointers to the       
  130.        Dwarf_Frame_Op structs executed.                     
  131.     */
  132.     Dwarf_Frame_Op          *curr_instr;
  133.     Dwarf_Chain             curr_instr_item, dealloc_instr_item;
  134.     Dwarf_Chain             head_instr_chain = NULL;
  135.     Dwarf_Chain             tail_instr_chain = NULL;
  136.     Dwarf_Frame_Op          *head_instr_block;
  137.  
  138.     /*
  139.         These are the alignment_factors taken from the
  140.         Cie provided.  When no input Cie is provided they
  141.         are set to 1, because only factored offsets are
  142.         required.
  143.     */
  144.     Dwarf_Sword            code_alignment_factor = 1;
  145.     Dwarf_Sword            data_alignment_factor = 1;
  146.     
  147.     /*
  148.         This flag indicates when an actual alignment factor
  149.         is needed.  So if a frame instruction that computes
  150.         an offset using an alignment factor is encountered
  151.         when this flag is set, an error is returned because
  152.         the Cie did not have a valid augmentation.
  153.     */
  154.     Dwarf_Bool              need_augmentation = false;
  155.  
  156.     Dwarf_Word              i;
  157.  
  158.     /* Initialize first row from associated Cie.    */
  159.     if (cie != NULL && cie->ci_initial_table != NULL) {
  160.         for (i = 0; i < DW_FRAME_LAST_REG_NUM; i++)
  161.             reg[i] = cie->ci_initial_table->fr_reg[i];
  162.     }
  163.     else {    /* initialize with same_value */
  164.         for (i = 0; i < DW_FRAME_LAST_REG_NUM; i++) {
  165.             reg[i].ru_is_off = 0; 
  166.             reg[i].ru_register = DW_FRAME_SAME_VAL;
  167.             reg[i].ru_offset = 0;
  168.     }
  169.     }
  170.  
  171.     /*
  172.     The idea here is that the code_alignment_factor and
  173.     data_alignment_factor which are needed for certain
  174.     instructions are valid only when the Cie has a proper
  175.     augmentation string.  So if the augmentation is not
  176.     right, only Frame instruction can be read.
  177.     */
  178.     if (cie != NULL && cie->ci_augmentation != NULL) {
  179.         code_alignment_factor = cie->ci_code_alignment_factor;
  180.         data_alignment_factor = cie->ci_data_alignment_factor;
  181.     }
  182.     else need_augmentation = !make_instr;
  183.  
  184.     instr_ptr = start_instr_ptr;
  185.     while (instr_ptr < final_instr_ptr && !search_over) {
  186.  
  187.         fp_instr_offset = instr_ptr - start_instr_ptr;
  188.         instr = *(Dwarf_Small *)instr_ptr;
  189.         instr_ptr = instr_ptr + sizeof(Dwarf_Small);
  190.  
  191.     fp_base_op = (instr & 0xc0)>>6;
  192.     if ((instr & 0xc0) == 0x00) {    
  193.         opcode = instr; /* is really extended op */
  194.          fp_extended_op = (instr & (~(0xc0))) & 0xff;
  195.     } else {
  196.         opcode = instr & 0xc0; /* is base op */
  197.          fp_extended_op = 0;
  198.     }
  199.  
  200.     fp_register = 0;
  201.     fp_offset = 0;
  202.         switch (opcode) {
  203.  
  204.             case DW_CFA_advance_loc : { /* base op */
  205.                 fp_offset = adv_pc = instr & DW_FRAME_INSTR_OFFSET_MASK;
  206.  
  207.                 if (need_augmentation) return(DF_NO_CIE_AUGMENTATION);
  208.                 adv_pc = adv_pc * code_alignment_factor;
  209.  
  210.                 search_over = search_pc && (loc+adv_pc > search_pc_val);
  211.                 /* If gone past pc needed, retain old pc.   */
  212.                 if (!search_over) loc = loc + adv_pc;
  213.                 break;
  214.             }
  215.  
  216.             case DW_CFA_offset : { /* base op */
  217.                 reg_no = (instr & DW_FRAME_INSTR_OFFSET_MASK);
  218.                 if (reg_no > DW_FRAME_LAST_REG_NUM){
  219.              return(DF_REG_NUM_TOO_HIGH);
  220.         }
  221.  
  222.                 factored_N_value = 
  223.                     _dwarf_decode_u_leb128(instr_ptr,&leb128_length);
  224.                 instr_ptr = instr_ptr + leb128_length;
  225.  
  226.                 fp_register = reg_no;
  227.                 fp_offset = factored_N_value; 
  228.  
  229.                 if (need_augmentation) return(DF_NO_CIE_AUGMENTATION);
  230.  
  231.                 reg[reg_no].ru_is_off = 1;
  232.                 reg[reg_no].ru_register = DW_FRAME_CFA_COL;
  233.                 reg[reg_no].ru_offset = factored_N_value * 
  234.                     data_alignment_factor;
  235.  
  236.                 break;
  237.             }
  238.  
  239.             case DW_CFA_restore : { /* base op */
  240.                 reg_no = (instr & DW_FRAME_INSTR_OFFSET_MASK);
  241.                 if (reg_no > DW_FRAME_LAST_REG_NUM)  {
  242.             return(DF_REG_NUM_TOO_HIGH);
  243.             }
  244.  
  245.                 fp_register = reg_no;
  246.  
  247.                 if (cie != NULL && cie->ci_initial_table != NULL)
  248.                     reg[reg_no] = cie->ci_initial_table->fr_reg[reg_no];
  249.                 else
  250.                     if (!make_instr) return(DF_MAKE_INSTR_NO_INIT);
  251.  
  252.                 break;
  253.             }
  254.             case DW_CFA_set_loc : {
  255.             READ_UNALIGNED(new_loc, instr_ptr, dbg->de_length_size);
  256.                 instr_ptr += dbg->de_length_size;
  257.                 if (new_loc <= loc) return(DF_NEW_LOC_LESS_OLD_LOC);
  258.  
  259.                 search_over = search_pc && (new_loc > search_pc_val);
  260.  
  261.                 /* If gone past pc needed, retain old pc.   */
  262.                 if (!search_over) loc = new_loc;
  263.                 fp_offset = new_loc;
  264.                 break;
  265.             }
  266.  
  267.             case DW_CFA_advance_loc1 : {
  268.                 fp_offset = adv_loc = *(Dwarf_Small *)instr_ptr;
  269.                 instr_ptr = instr_ptr + sizeof(Dwarf_Small);
  270.  
  271.                 if (need_augmentation) return(DF_NO_CIE_AUGMENTATION);
  272.                 adv_loc *= code_alignment_factor;
  273.  
  274.                 search_over = search_pc && 
  275.                     (loc + adv_loc > search_pc_val);
  276.  
  277.                 /* If gone past pc needed, retain old pc.   */
  278.                 if (!search_over) loc = loc + adv_loc;
  279.                 break;
  280.             }
  281.  
  282.             case DW_CFA_advance_loc2 : {
  283.             READ_UNALIGNED(adv_loc, instr_ptr, sizeof(Dwarf_Half));
  284.                 instr_ptr += sizeof(Dwarf_Half);
  285.                 fp_offset = adv_loc;
  286.  
  287.                 if (need_augmentation) return(DF_NO_CIE_AUGMENTATION);
  288.                 adv_loc *= code_alignment_factor;
  289.  
  290.                 search_over = search_pc && 
  291.                     (loc+adv_loc > search_pc_val);
  292.  
  293.                 /* If gone past pc needed, retain old pc.   */
  294.                 if (!search_over) loc = loc + adv_loc;
  295.                 break;
  296.             }
  297.  
  298.             case DW_CFA_advance_loc4 : {
  299.             READ_UNALIGNED(adv_loc, instr_ptr, sizeof(Dwarf_Word));
  300.                 instr_ptr += sizeof(Dwarf_Word);
  301.                 fp_offset = adv_loc;
  302.  
  303.                 if (need_augmentation) return(DF_NO_CIE_AUGMENTATION);
  304.                 adv_loc *= code_alignment_factor;
  305.  
  306.                 search_over = search_pc && 
  307.                     (loc+adv_loc > search_pc_val);
  308.  
  309.                 /* If gone past pc needed, retain old pc.   */
  310.                 if (!search_over) loc = loc + adv_loc;
  311.                 break;
  312.             }
  313.  
  314.             case DW_CFA_offset_extended : {
  315.         DECODE_LEB128_UWORD(instr_ptr, reg_no)
  316.                 if (reg_no > DW_FRAME_LAST_REG_NUM)  {
  317.             return(DF_REG_NUM_TOO_HIGH);
  318.             }
  319.                 factored_N_value = 
  320.                     _dwarf_decode_u_leb128(instr_ptr,&leb128_length);
  321.                 instr_ptr = instr_ptr + leb128_length;
  322.  
  323.                 if (need_augmentation) return(DF_NO_CIE_AUGMENTATION);
  324.                 reg[reg_no].ru_is_off = 1;
  325.                 reg[reg_no].ru_register = DW_FRAME_CFA_COL;
  326.                 reg[reg_no].ru_offset = factored_N_value *
  327.                     data_alignment_factor;
  328.  
  329.                 fp_register = reg_no;
  330.                 fp_offset = factored_N_value;
  331.                 break;
  332.             }
  333.  
  334.             case DW_CFA_restore_extended : {
  335.         DECODE_LEB128_UWORD(instr_ptr, reg_no)
  336.                 if (reg_no > DW_FRAME_LAST_REG_NUM)  {
  337.             return(DF_REG_NUM_TOO_HIGH);
  338.             }
  339.  
  340.                 if (cie != NULL && cie->ci_initial_table != NULL)
  341.                     reg[reg_no] = 
  342.                         cie->ci_initial_table->fr_reg[reg_no];
  343.                 else
  344.                     if (!make_instr) return(DF_MAKE_INSTR_NO_INIT);
  345.  
  346.                 fp_register = reg_no;
  347.                 break;
  348.             }
  349.  
  350.             case DW_CFA_undefined : {
  351.         DECODE_LEB128_UWORD(instr_ptr, reg_no)
  352.                 if (reg_no > DW_FRAME_LAST_REG_NUM)  {
  353.             return(DF_REG_NUM_TOO_HIGH);
  354.             }
  355.  
  356.                 reg[reg_no].ru_is_off = 0;
  357.                 reg[reg_no].ru_register = DW_FRAME_UNDEFINED_VAL;
  358.                 reg[reg_no].ru_offset = 0;
  359.  
  360.                 fp_register = reg_no;
  361.                 break;
  362.             }
  363.  
  364.             case DW_CFA_same_value : {
  365.         DECODE_LEB128_UWORD(instr_ptr, reg_no)
  366.                 if (reg_no > DW_FRAME_LAST_REG_NUM)  {
  367.             return(DF_REG_NUM_TOO_HIGH);
  368.             }
  369.  
  370.                 reg[reg_no].ru_is_off = 0;
  371.                 reg[reg_no].ru_register = DW_FRAME_SAME_VAL;
  372.                 reg[reg_no].ru_offset = 0;
  373.                 fp_register = reg_no;
  374.                 break;
  375.             }
  376.  
  377.             case DW_CFA_register : {
  378.         DECODE_LEB128_UWORD(instr_ptr, reg_noA)
  379.                 if (reg_noA > DW_FRAME_LAST_REG_NUM)  {
  380.             return(DF_REG_NUM_TOO_HIGH);
  381.             }
  382.         DECODE_LEB128_UWORD(instr_ptr, reg_noB)
  383.                 if (reg_noB > DW_FRAME_LAST_REG_NUM)  {
  384.             return(DF_REG_NUM_TOO_HIGH);
  385.             }
  386.  
  387.                 reg[reg_noA].ru_is_off = 0;
  388.                 reg[reg_noA].ru_register = reg_noB;
  389.                 reg[reg_noA].ru_offset = 0;
  390.  
  391.                 fp_register = reg_noA;
  392.                 fp_offset = reg_noB;
  393.                 break;
  394.             }
  395.  
  396.             case DW_CFA_remember_state : {
  397.                 stack_table = (Dwarf_Frame)
  398.                     _dwarf_get_alloc(dbg, DW_DLA_FRAME, 1);
  399.                 if (stack_table == NULL) return(DF_ALLOC_FAIL);
  400.  
  401.                 for (i = 0; i < DW_FRAME_LAST_REG_NUM; i++)
  402.                     stack_table->fr_reg[i] = reg[i];
  403.  
  404.                 if (top_stack != NULL)
  405.                     stack_table->fr_next = top_stack;
  406.                 top_stack = stack_table;
  407.  
  408.                 break;
  409.             }
  410.  
  411.             case DW_CFA_restore_state : {
  412.                 if (top_stack == NULL) return(DF_POP_EMPTY_STACK);
  413.                 stack_table = top_stack;
  414.                 top_stack = stack_table->fr_next;
  415.  
  416.                 for (i = 0; i < DW_FRAME_LAST_REG_NUM; i++)
  417.                     reg[i] = stack_table->fr_reg[i];
  418.  
  419.                 dwarf_dealloc(dbg, stack_table, DW_DLA_FRAME);
  420.                 break;
  421.             }
  422.  
  423.             case DW_CFA_def_cfa : {
  424.         DECODE_LEB128_UWORD(instr_ptr, reg_no)
  425.                 if (reg_no > DW_FRAME_LAST_REG_NUM)  {
  426.             return(DF_REG_NUM_TOO_HIGH);
  427.             }
  428.  
  429.                 factored_N_value = 
  430.                     _dwarf_decode_u_leb128(instr_ptr,&leb128_length);
  431.                 instr_ptr = instr_ptr + leb128_length;
  432.  
  433.                 if (need_augmentation) return(DF_NO_CIE_AUGMENTATION);
  434.                 reg[DW_FRAME_CFA_COL].ru_is_off = 1;
  435.                 reg[DW_FRAME_CFA_COL].ru_register = reg_no;
  436.                 reg[DW_FRAME_CFA_COL].ru_offset = factored_N_value;
  437.  
  438.                 fp_register = reg_no;
  439.                 fp_offset = factored_N_value;
  440.                 break;
  441.             }
  442.  
  443.             case DW_CFA_def_cfa_register : {
  444.         DECODE_LEB128_UWORD(instr_ptr, reg_no)
  445.                 if (reg_no > DW_FRAME_LAST_REG_NUM)  {
  446.             return(DF_REG_NUM_TOO_HIGH);
  447.             }
  448.  
  449.                 reg[DW_FRAME_CFA_COL].ru_is_off = 0;
  450.                 reg[DW_FRAME_CFA_COL].ru_register = reg_no;
  451.                 reg[DW_FRAME_CFA_COL].ru_offset = 0;
  452.                 fp_register = reg_no;
  453.                 break;
  454.             }
  455.  
  456.             case DW_CFA_def_cfa_offset : {
  457.                 factored_N_value = 
  458.                     _dwarf_decode_u_leb128(instr_ptr,&leb128_length);
  459.                 instr_ptr = instr_ptr + leb128_length;
  460.  
  461.                 if (need_augmentation) return(DF_NO_CIE_AUGMENTATION);
  462.                 reg[DW_FRAME_CFA_COL].ru_offset = factored_N_value;
  463.  
  464.                 fp_offset = factored_N_value;
  465.                 break;
  466.             }
  467.  
  468.             case DW_CFA_nop : {
  469.                 break;
  470.                 }
  471.         }
  472.  
  473.         if (make_instr) {
  474.             instr_count++;
  475.  
  476.             curr_instr = (Dwarf_Frame_Op *)
  477.                 _dwarf_get_alloc(dbg, DW_DLA_FRAME_OP, 1);
  478.             if (curr_instr == NULL) return(DF_ALLOC_FAIL);
  479.  
  480.             curr_instr->fp_base_op = fp_base_op;
  481.             curr_instr->fp_extended_op = fp_extended_op;
  482.             curr_instr->fp_register = fp_register;
  483.             curr_instr->fp_offset = fp_offset;
  484.             curr_instr->fp_instr_offset = fp_instr_offset;
  485.  
  486.             curr_instr_item = (Dwarf_Chain)
  487.                 _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
  488.             if (curr_instr_item == NULL) return(DF_ALLOC_FAIL);
  489.  
  490.             curr_instr_item->ch_item = curr_instr;
  491.             if (head_instr_chain == NULL) 
  492.                 head_instr_chain = tail_instr_chain = curr_instr_item;
  493.             else {
  494.                 tail_instr_chain->ch_next = curr_instr_item;
  495.                 tail_instr_chain = curr_instr_item;
  496.             }
  497.         }
  498.  
  499.     }
  500.  
  501.     /* 
  502.        If frame instruction decoding was right      
  503.        we would stop exactly at final_instr_ptr.    
  504.     */
  505.     if (instr_ptr > final_instr_ptr) 
  506.         return(DF_FRAME_DECODING_ERROR);
  507.  
  508.     /* Create the last row generated.   */
  509.     if (table != NULL) {
  510.         table->fr_loc = loc;
  511.         for (i = 0; i < DW_FRAME_LAST_REG_NUM; i++)
  512.             table->fr_reg[i] = reg[i];
  513.     }
  514.  
  515.     /* Dealloc anything remaining on stack. */
  516.     for (; top_stack != NULL; ) {
  517.         stack_table = top_stack;
  518.         top_stack = top_stack->fr_next;
  519.         dwarf_dealloc(dbg, stack_table, DW_DLA_FRAME);
  520.     }
  521.  
  522.     if (make_instr) {
  523.         /* Allocate list of pointers to Dwarf_Frame_Op's.   */
  524.         head_instr_block = (Dwarf_Frame_Op *)
  525.             _dwarf_get_alloc(dbg, DW_DLA_FRAME_BLOCK, instr_count);
  526.         if (head_instr_block == NULL) return(DF_ALLOC_FAIL);
  527.  
  528.         /* 
  529.            Store pointers to Dwarf_Frame_Op's in this list  
  530.            and deallocate the structs that chain the        
  531.            Dwarf_Frame_Op's.                                
  532.         */
  533.         curr_instr_item = head_instr_chain;
  534.         for (i = 0 ; i < instr_count; i++) {
  535.             *(head_instr_block + i) = 
  536.         *(Dwarf_Frame_Op *)curr_instr_item->ch_item;
  537.             dealloc_instr_item = curr_instr_item;
  538.             curr_instr_item = curr_instr_item->ch_next;
  539.         dwarf_dealloc(dbg, dealloc_instr_item->ch_item, DW_DLA_FRAME_OP);
  540.             dwarf_dealloc(dbg, dealloc_instr_item, DW_DLA_CHAIN);
  541.         }
  542.         *ret_frame_instr = head_instr_block;
  543.  
  544.         return(instr_count);
  545.     }
  546.     else
  547.         return(1);
  548. }
  549.  
  550.  
  551. int
  552. dwarf_get_fde_list (
  553.     Dwarf_Debug     dbg,
  554.     Dwarf_Cie       **cie_data,
  555.     Dwarf_Signed    *cie_element_count,
  556.     Dwarf_Fde       **fde_data,
  557.     Dwarf_Signed    *fde_element_count,
  558.     Dwarf_Error     *error
  559. )
  560. {
  561.     /* Scans the debug_frame section. */
  562.     Dwarf_Small     *frame_ptr;
  563.  
  564.     /* Points to the start of the current Fde or Cie. */
  565.     Dwarf_Small     *start_frame_ptr;
  566.  
  567.     /* Fields for the current Cie being read. */
  568.     Dwarf_Unsigned  length;        /* READ_UNALIGNED needs 8 byte dest */
  569.     Dwarf_Unsigned  offset;
  570.     Dwarf_Small     version;
  571.     Dwarf_Small     *augmentation;
  572.     Dwarf_Word      code_alignment_factor;
  573.     Dwarf_Sword     data_alignment_factor;
  574.     Dwarf_Small     return_address_register;
  575.  
  576.     /* 
  577.        New_cie points to the Cie being read, and    
  578.        head_cie_ptr and cur_cie_ptr are used  for   
  579.        chaining them up in sequence.                
  580.     */
  581.     Dwarf_Cie       new_cie;
  582.     Dwarf_Cie       head_cie_ptr = NULL;
  583.     Dwarf_Cie       cur_cie_ptr;
  584.     Dwarf_Word      cie_count = 0;
  585.  
  586.     /* 
  587.        Points to a list of contiguous pointers  
  588.        to Dwarf_Cie structures.                 
  589.     */
  590.     Dwarf_Cie       *cie_list_ptr;
  591.  
  592.     /* Fields for the current Fde being read.   */
  593.     Dwarf_Addr      initial_location;
  594.     Dwarf_Addr      address_range;
  595.  
  596.     /* 
  597.        New_fde points to the current Fde being read,    
  598.        and head_fde_ptr and cur_fde_ptr are used to     
  599.        chain them up.                                   
  600.     */
  601.     Dwarf_Fde       new_fde;
  602.     Dwarf_Fde       head_fde_ptr = NULL;
  603.     Dwarf_Fde       cur_fde_ptr;
  604.     Dwarf_Word        fde_count = 0;
  605.  
  606.     /* 
  607.        Points to a list of contiguous pointers to   
  608.        Dwarf_Fde structures.                        
  609.     */
  610.     Dwarf_Fde       *fde_list_ptr;
  611.  
  612.     /* 
  613.        Is used to check the offset field in the Fde 
  614.        by checking for a Cie at this address.       
  615.     */
  616.     Dwarf_Small     *fde_cie_ptr;
  617.  
  618.     Dwarf_Word      leb128_length;
  619.     Dwarf_Word      i, j;
  620.  
  621.  
  622.     frame_ptr = dbg->de_debug_frame;
  623.  
  624.     if(frame_ptr == 0) {
  625.     return DW_DLV_NO_ENTRY;
  626.     }
  627.  
  628.     while (frame_ptr < dbg->de_debug_frame + dbg->de_debug_frame_size) {
  629.  
  630.         start_frame_ptr = frame_ptr;
  631.  
  632.     READ_UNALIGNED(length, frame_ptr, dbg->de_length_size);
  633.         frame_ptr += dbg->de_length_size;
  634.         if (length % dbg->de_length_size != 0) {
  635.         _dwarf_error(dbg,error,DW_DLE_DEBUG_FRAME_LENGTH_BAD); 
  636.         return(DW_DLV_ERROR);
  637.     }
  638.  
  639.     READ_UNALIGNED(offset, frame_ptr, dbg->de_length_size);
  640.     SIGN_EXTEND(offset, dbg->de_length_size);
  641.  
  642.         frame_ptr += dbg->de_length_size;
  643.         if (offset == DW_CIE_ID) {
  644.  
  645.             version = *(Dwarf_Small *)frame_ptr;
  646.             frame_ptr++;
  647.             if (version != DW_CIE_VERSION) {
  648.         _dwarf_error(dbg,error,DW_DLE_FRAME_VERSION_BAD);
  649.         return(DW_DLV_ERROR);
  650.         }
  651.  
  652.             if (strcmp(frame_ptr,DW_DEBUG_FRAME_AUGMENTER_STRING) != 0 &&
  653.                 strcmp(frame_ptr,DW_NULL_STRING) != 0)
  654.                 frame_ptr = start_frame_ptr + length + 
  655.             dbg->de_length_size;
  656.             else {
  657.                 augmentation = frame_ptr;
  658.                 frame_ptr = frame_ptr + strlen(frame_ptr) + 1;
  659.  
  660.         DECODE_LEB128_UWORD(frame_ptr, code_alignment_factor)
  661.  
  662.                 data_alignment_factor = 
  663.                     _dwarf_decode_s_leb128(frame_ptr,&leb128_length);
  664.                 frame_ptr = frame_ptr + leb128_length;
  665.  
  666.                 return_address_register = *(Dwarf_Small *)frame_ptr;
  667.                 if (return_address_register > DW_FRAME_LAST_REG_NUM) {
  668.             _dwarf_error(dbg,error,DW_DLE_CIE_RET_ADDR_REG_ERROR);
  669.             return(DW_DLV_ERROR);
  670.         }
  671.                 frame_ptr++;
  672.             }
  673.  
  674.             new_cie = (Dwarf_Cie)_dwarf_get_alloc(dbg, DW_DLA_CIE, 1);
  675.             if (new_cie == NULL) {
  676.         _dwarf_error(dbg,error,DW_DLE_ALLOC_FAIL);
  677.         return(DW_DLV_ERROR);
  678.         }
  679.  
  680.             new_cie->ci_length = length;
  681.             new_cie->ci_augmentation = augmentation;
  682.  
  683.             new_cie->ci_data_alignment_factor = data_alignment_factor;
  684.             new_cie->ci_code_alignment_factor = code_alignment_factor;
  685.             new_cie->ci_return_address_register = return_address_register;
  686.             new_cie->ci_cie_start = start_frame_ptr;
  687.             new_cie->ci_cie_instr_start = frame_ptr;
  688.             new_cie->ci_dbg = dbg;
  689.  
  690.             cie_count++;
  691.             if (head_cie_ptr == NULL)
  692.                 head_cie_ptr = cur_cie_ptr = new_cie;
  693.             else {
  694.                 cur_cie_ptr->ci_next = new_cie;
  695.                 cur_cie_ptr = new_cie;
  696.             }
  697.         } else {
  698.         Dwarf_Small *initloc = frame_ptr;
  699.  
  700.         READ_UNALIGNED(initial_location, frame_ptr, dbg->de_length_size);
  701.             frame_ptr += dbg->de_length_size;
  702.  
  703.         READ_UNALIGNED(address_range, frame_ptr, dbg->de_length_size);
  704.             frame_ptr += dbg->de_length_size;
  705.  
  706.             new_fde = (Dwarf_Fde)_dwarf_get_alloc(dbg, DW_DLA_FDE, 1);
  707.             if (new_fde == NULL) {
  708.         _dwarf_error(dbg,error,DW_DLE_ALLOC_FAIL);
  709.         return(DW_DLV_ERROR);
  710.         }
  711.  
  712.             new_fde->fd_length = length;
  713.             new_fde->fd_cie_offset = offset;
  714.             new_fde->fd_initial_location = initial_location;
  715.             new_fde->fd_initial_loc_pos =  initloc;
  716.             new_fde->fd_address_range = address_range;
  717.             new_fde->fd_fde_start = start_frame_ptr;
  718.             new_fde->fd_fde_instr_start = frame_ptr;
  719.             new_fde->fd_dbg = dbg;
  720.  
  721.             fde_count++;
  722.             if (head_fde_ptr == NULL)
  723.                 head_fde_ptr = cur_fde_ptr = new_fde;
  724.             else {
  725.                 cur_fde_ptr->fd_next = new_fde;
  726.                 cur_fde_ptr = new_fde;
  727.             }
  728.         }
  729.  
  730.         /* Skip over instructions to start of next frame. */
  731.     frame_ptr = start_frame_ptr + length + dbg->de_length_size;
  732.     }
  733.  
  734.     if (cie_count > 0) {
  735.     cie_list_ptr = (Dwarf_Cie *)
  736.         _dwarf_get_alloc(dbg, DW_DLA_LIST, cie_count);
  737.     }
  738.     else {
  739.     return (DW_DLV_NO_ENTRY);
  740.     }
  741.     if (cie_list_ptr == NULL) {
  742.     _dwarf_error(dbg,error,DW_DLE_ALLOC_FAIL);
  743.     return(DW_DLV_ERROR);
  744.     }
  745.     /* Return arguments. */
  746.     *cie_data = cie_list_ptr;
  747.     *cie_element_count = cie_count;
  748.     dbg->de_cie_data = cie_list_ptr;
  749.     dbg->de_cie_count = cie_count;
  750.  
  751.     cur_cie_ptr = head_cie_ptr;
  752.     for (i = 0; i < cie_count; i++) {
  753.         *(cie_list_ptr + i) = cur_cie_ptr;
  754.         cur_cie_ptr = cur_cie_ptr->ci_next;
  755.     }
  756.  
  757.     if (fde_count > 0) {
  758.     fde_list_ptr = (Dwarf_Fde *)
  759.         _dwarf_get_alloc(dbg, DW_DLA_LIST, fde_count);
  760.     }
  761.     else {
  762.     return(DW_DLV_NO_ENTRY);
  763.     }
  764.     if (fde_list_ptr == NULL) {
  765.     _dwarf_error(dbg,error,DW_DLE_ALLOC_FAIL);
  766.     return(DW_DLV_ERROR);
  767.     }
  768.     /* Return arguments. */
  769.     *fde_data = fde_list_ptr;
  770.     *fde_element_count = fde_count;
  771.     dbg->de_fde_data = fde_list_ptr;
  772.     dbg->de_fde_count = fde_count;
  773.  
  774.     cur_fde_ptr = head_fde_ptr;
  775.     for (i = 0; i < fde_count; i++) {
  776.         *(fde_list_ptr + i) = cur_fde_ptr;
  777.  
  778.         fde_cie_ptr = (Dwarf_Small *)(dbg->de_debug_frame + 
  779.             cur_fde_ptr->fd_cie_offset);
  780.         for (j = 0; j < cie_count; j++)
  781.             if (((Dwarf_Cie)*(cie_list_ptr+j))->ci_cie_start == fde_cie_ptr) 
  782.                 break;
  783.         if (j == cie_count) {
  784.         _dwarf_error(dbg,error,DW_DLE_NO_CIE_FOR_FDE);
  785.         return(DW_DLV_ERROR);
  786.     }
  787.         else {
  788.             cur_fde_ptr->fd_cie_index = j;
  789.             cur_fde_ptr->fd_cie = *(cie_list_ptr + j);
  790.         }
  791.  
  792.         cur_fde_ptr = cur_fde_ptr->fd_next;
  793.     }
  794.  
  795.     return(DW_DLV_OK);
  796. }
  797.  
  798. int
  799. dwarf_get_fde_for_die(
  800.     Dwarf_Debug        dbg,
  801.     Dwarf_Die        die,
  802.     Dwarf_Fde       * ret_fde,
  803.     Dwarf_Error        *error
  804. )
  805. {
  806.     Dwarf_Attribute     attr;
  807.     Dwarf_Unsigned     fde_offset;
  808.     Dwarf_Signed        signdval;
  809.     Dwarf_Unsigned      length;
  810.     Dwarf_Signed     offset;
  811.     Dwarf_Sword     temp_offset;
  812.     Dwarf_Addr         initial_location;
  813.     Dwarf_Addr         address_range;
  814.     Dwarf_Fde         new_fde;
  815.     char         *fde_ptr;
  816.     char         *cie_ptr;
  817.     char         *start_cie_ptr;
  818.     Dwarf_Cie        new_cie;
  819.  
  820.     /* Fields for the current Cie being read. */
  821.     Dwarf_Small     version;
  822.     Dwarf_Small     *augmentation;
  823.     Dwarf_Word      code_alignment_factor;
  824.     Dwarf_Sword     data_alignment_factor;
  825.     Dwarf_Small     return_address_register;
  826.     int resattr;
  827.     int sdatares;
  828.  
  829.     Dwarf_Word      leb128_length;
  830.  
  831.     if (die == NULL) {
  832.     _dwarf_error(NULL, error, DW_DLE_DIE_NULL);
  833.     return(DW_DLV_ERROR);
  834.     }
  835.  
  836.     resattr = dwarf_attr(die, DW_AT_MIPS_fde,&attr, error);
  837.     if(resattr != DW_DLV_OK) {
  838.     return resattr;
  839.     }
  840.  
  841.     /* why is this formsdata? FIX*/
  842.     sdatares = dwarf_formsdata(attr,&signdval,error);
  843.     if(sdatares != DW_DLV_OK){
  844.     return sdatares;
  845.     }
  846.     fde_offset = signdval;
  847.     fde_ptr = dbg->de_debug_frame+fde_offset;
  848.  
  849.     READ_UNALIGNED(length, fde_ptr, dbg->de_length_size);
  850.     fde_ptr += dbg->de_length_size;
  851.  
  852.     if (length % dbg->de_length_size != 0) {
  853.     _dwarf_error(dbg,error,DW_DLE_DEBUG_FRAME_LENGTH_BAD); 
  854.     return( DW_DLV_ERROR);
  855.     }
  856.  
  857.     READ_UNALIGNED(offset, fde_ptr, dbg->de_length_size);
  858.     SIGN_EXTEND(offset, dbg->de_length_size);
  859.     fde_ptr += dbg->de_length_size;
  860.  
  861.     READ_UNALIGNED(initial_location, fde_ptr, dbg->de_length_size);
  862.     fde_ptr += dbg->de_length_size;
  863.  
  864.     READ_UNALIGNED(address_range, fde_ptr, dbg->de_length_size);
  865.     fde_ptr += dbg->de_length_size;
  866.  
  867.     new_fde = (Dwarf_Fde)_dwarf_get_alloc(dbg, DW_DLA_FDE, 1);
  868.     if (new_fde == NULL) {
  869.     _dwarf_error(dbg,error,DW_DLE_ALLOC_FAIL);
  870.     return(DW_DLV_ERROR);
  871.     }
  872.  
  873.     new_fde->fd_length = length;
  874.     new_fde->fd_cie_offset = offset;
  875.     new_fde->fd_initial_location = initial_location;
  876.     new_fde->fd_address_range = address_range;
  877.     new_fde->fd_fde_start = dbg->de_debug_frame+fde_offset;
  878.     new_fde->fd_fde_instr_start = fde_ptr;
  879.     new_fde->fd_dbg = dbg;
  880.  
  881.     /* now read the cie corresponding to the fde */
  882.     cie_ptr = dbg->de_debug_frame+offset;
  883.     start_cie_ptr = cie_ptr;
  884.  
  885.     READ_UNALIGNED(length, cie_ptr, dbg->de_length_size);
  886.     cie_ptr += dbg->de_length_size;
  887.     
  888.     if (length % dbg->de_length_size != 0) {
  889.     _dwarf_error(dbg,error,DW_DLE_DEBUG_FRAME_LENGTH_BAD); 
  890.     return(DW_DLV_ERROR);
  891.     }
  892.  
  893.     READ_UNALIGNED(offset, cie_ptr, dbg->de_length_size);
  894.     SIGN_EXTEND(offset, dbg->de_length_size);
  895.     cie_ptr += dbg->de_length_size;
  896.  
  897.     if (offset == DW_CIE_ID) {
  898.         version = *(Dwarf_Small *)cie_ptr;
  899.         cie_ptr++;
  900.         if (version != DW_CIE_VERSION) {
  901.         _dwarf_error(dbg,error,DW_DLE_FRAME_VERSION_BAD);
  902.         return(DW_DLV_ERROR);
  903.     }
  904.         if (strcmp(cie_ptr,DW_DEBUG_FRAME_AUGMENTER_STRING) != 0 &&
  905.             strcmp(cie_ptr,DW_NULL_STRING) != 0)
  906.             cie_ptr = start_cie_ptr + length + 
  907.         dbg->de_length_size;
  908.         else {
  909.             augmentation = cie_ptr;
  910.             cie_ptr = cie_ptr + strlen(cie_ptr) + 1;
  911.  
  912.         DECODE_LEB128_UWORD(cie_ptr, code_alignment_factor)
  913.  
  914.             data_alignment_factor = 
  915.                 _dwarf_decode_s_leb128(cie_ptr,&leb128_length);
  916.             cie_ptr = cie_ptr + leb128_length;
  917.  
  918.             return_address_register = *(Dwarf_Small *)cie_ptr;
  919.             if (return_address_register > DW_FRAME_LAST_REG_NUM) {
  920.         _dwarf_error(dbg,error,DW_DLE_CIE_RET_ADDR_REG_ERROR);
  921.             return( DW_DLV_ERROR);
  922.         }
  923.             cie_ptr++;
  924.         }
  925.  
  926.         new_cie = (Dwarf_Cie)_dwarf_get_alloc(dbg, DW_DLA_CIE, 1);
  927.         if (new_cie == NULL) {
  928.         _dwarf_error(dbg,error,DW_DLE_ALLOC_FAIL);
  929.         return(DW_DLV_ERROR);
  930.     }
  931.  
  932.     new_cie->ci_initial_table = NULL;
  933.         new_cie->ci_length = length;
  934.         new_cie->ci_augmentation = augmentation;
  935.         new_cie->ci_data_alignment_factor = data_alignment_factor;
  936.         new_cie->ci_code_alignment_factor = code_alignment_factor;
  937.         new_cie->ci_return_address_register = return_address_register;
  938.         new_cie->ci_cie_start = start_cie_ptr;
  939.         new_cie->ci_cie_instr_start = cie_ptr;
  940.         new_cie->ci_dbg = dbg;
  941.     }
  942.     else {
  943.     _dwarf_error(dbg,error,DW_DLE_NO_CIE_FOR_FDE);
  944.     return(DW_DLV_ERROR);
  945.     }
  946.     new_fde->fd_cie = new_cie;
  947.  
  948.     *ret_fde = new_fde;
  949.     return DW_DLV_OK;
  950. }
  951.  
  952.  
  953. int
  954. dwarf_get_fde_range (
  955.     Dwarf_Fde       fde,
  956.     Dwarf_Addr      *low_pc,
  957.     Dwarf_Unsigned  *func_length,
  958.     Dwarf_Ptr       *fde_bytes,
  959.     Dwarf_Unsigned  *fde_byte_length,
  960.     Dwarf_Off       *cie_offset,
  961.     Dwarf_Signed    *cie_index,
  962.     Dwarf_Off       *fde_offset,
  963.     Dwarf_Error     *error
  964. )
  965. {
  966.     Dwarf_Debug     dbg;
  967.     Dwarf_Fde       fde_ptr;
  968.  
  969.     if (fde == NULL) {
  970.     _dwarf_error(NULL,error,DW_DLE_FDE_NULL);
  971.     return(DW_DLV_ERROR);
  972.     }
  973.  
  974.     dbg = fde->fd_dbg;
  975.     if (dbg == NULL) {
  976.     _dwarf_error(NULL,error,DW_DLE_FDE_DBG_NULL);
  977.     return(DW_DLV_ERROR);
  978.     }
  979.  
  980.     if (low_pc != NULL)
  981.         *low_pc = fde->fd_initial_location;
  982.     if (func_length != NULL)
  983.         *func_length = fde->fd_address_range;
  984.     if (fde_bytes != NULL)
  985.         *fde_bytes = fde->fd_fde_start;
  986.     if (fde_byte_length != NULL)
  987.         *fde_byte_length = fde->fd_length;
  988.     if (cie_offset != NULL)
  989.         *cie_offset = fde->fd_cie_offset;
  990.     if (cie_index != NULL)
  991.         *cie_index = fde->fd_cie_index;
  992.     if (fde_offset != NULL)
  993.         *fde_offset = fde->fd_fde_start - dbg->de_debug_frame;
  994.  
  995.     return DW_DLV_OK;
  996. }
  997.  
  998.  
  999. int
  1000. dwarf_get_cie_info (
  1001.     Dwarf_Cie       cie,
  1002.     Dwarf_Unsigned  *bytes_in_cie,
  1003.     Dwarf_Small     *version,
  1004.     char           **augmenter,
  1005.     Dwarf_Unsigned  *code_alignment_factor,
  1006.     Dwarf_Signed    *data_alignment_factor,
  1007.     Dwarf_Half      *return_address_register,
  1008.     Dwarf_Ptr       *initial_instructions,
  1009.     Dwarf_Unsigned  *initial_instructions_length,
  1010.     Dwarf_Error     *error
  1011. )
  1012. {
  1013.     Dwarf_Debug     dbg;
  1014.     Dwarf_Cie       cie_ptr;
  1015.  
  1016.     if (cie == NULL) {
  1017.     _dwarf_error(NULL,error,DW_DLE_CIE_NULL);
  1018.     return(DW_DLV_ERROR);
  1019.     }
  1020.  
  1021.     dbg = cie->ci_dbg;
  1022.     if (dbg == NULL) {
  1023.     _dwarf_error(NULL,error,DW_DLE_CIE_DBG_NULL);
  1024.     return(DW_DLV_ERROR);
  1025.     }
  1026.  
  1027.     if (version != NULL)
  1028.         *version = DW_CIE_VERSION;
  1029.     if (augmenter != NULL)
  1030.         *augmenter = cie->ci_augmentation;
  1031.     if (code_alignment_factor != NULL)
  1032.         *code_alignment_factor = cie->ci_code_alignment_factor;
  1033.     if (data_alignment_factor != NULL)
  1034.         *data_alignment_factor = cie->ci_data_alignment_factor;
  1035.     if (return_address_register != NULL)
  1036.         *return_address_register = cie->ci_return_address_register;
  1037.     if (initial_instructions != NULL)
  1038.         *initial_instructions = cie->ci_cie_instr_start;
  1039.     if (initial_instructions_length != NULL)
  1040.         *initial_instructions_length = cie->ci_length + 
  1041.         dbg->de_length_size - 
  1042.         (cie->ci_cie_instr_start - cie->ci_cie_start);
  1043.  
  1044.     *bytes_in_cie = (cie->ci_length);
  1045.     DW_DLV_OK;
  1046. }
  1047.  
  1048.  
  1049. int
  1050. dwarf_get_fde_info_for_reg (
  1051.     Dwarf_Fde       fde,
  1052.     Dwarf_Half      table_column,
  1053.     Dwarf_Addr      pc_requested,
  1054.     Dwarf_Signed   *offset_relevant,
  1055.     Dwarf_Signed    *register_num,
  1056.     Dwarf_Signed    *offset,
  1057.     Dwarf_Addr        *row_pc,
  1058.     Dwarf_Error     *error
  1059. )
  1060. {
  1061.     Dwarf_Debug             dbg;
  1062.     Dwarf_Fde               fde_ptr;
  1063.     struct Dwarf_Frame_s    fde_table;
  1064.     Dwarf_Cie               cie;
  1065.     Dwarf_Sword            i;
  1066.  
  1067.     if (fde == NULL) {
  1068.     _dwarf_error(NULL,error,DW_DLE_FDE_NULL);
  1069.     return(DW_DLV_ERROR);
  1070.     }
  1071.  
  1072.     if (table_column > DW_FRAME_LAST_REG_NUM) {
  1073.     _dwarf_error(NULL,error,DW_DLE_FRAME_TABLE_COL_BAD);
  1074.     return(DW_DLV_ERROR);
  1075.     }
  1076.  
  1077.     dbg = fde->fd_dbg;
  1078.     if (dbg == NULL) {
  1079.     _dwarf_error(NULL,error,DW_DLE_FDE_DBG_NULL);
  1080.     return(DW_DLV_ERROR);
  1081.     }
  1082.  
  1083.     if (pc_requested < fde->fd_initial_location ||
  1084.         pc_requested >= fde->fd_initial_location + fde->fd_address_range) {
  1085.     _dwarf_error(dbg,error,DW_DLE_PC_NOT_IN_FDE_RANGE);
  1086.     return(DW_DLV_ERROR);
  1087.     }
  1088.  
  1089.     cie = fde->fd_cie;
  1090.     if (cie->ci_initial_table == NULL) {
  1091.     cie->ci_initial_table = _dwarf_get_alloc(dbg, DW_DLA_FRAME, 1);
  1092.     if (cie->ci_initial_table == NULL) {
  1093.         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
  1094.         return(DW_DLV_ERROR);
  1095.     }
  1096.         for (i = 0; i < DW_FRAME_LAST_REG_NUM; i++) {
  1097.             cie->ci_initial_table->fr_reg[i].ru_is_off = 0; 
  1098.             cie->ci_initial_table->fr_reg[i].ru_register = DW_FRAME_SAME_VAL;
  1099.             cie->ci_initial_table->fr_reg[i].ru_offset = 0;
  1100.     }
  1101.         if (_dwarf_exec_frame_instr(false, NULL, false, NULL, 0,
  1102.             cie->ci_cie_instr_start, 
  1103.             cie->ci_cie_start + cie->ci_length + dbg->de_length_size,
  1104.             cie->ci_initial_table, cie, dbg) <= 0) {
  1105.         _dwarf_error(dbg,error,DW_DLE_CIE_INSTR_EXEC_ERROR);
  1106.         return(DW_DLV_ERROR);
  1107.     }
  1108.     }
  1109.  
  1110.     if (_dwarf_exec_frame_instr (false, NULL, true, pc_requested, 
  1111.     fde->fd_initial_location, fde->fd_fde_instr_start, 
  1112.         fde->fd_fde_start + fde->fd_length + dbg->de_length_size,
  1113.         &fde_table, cie, dbg) <= 0) {
  1114.     _dwarf_error(dbg,error,DW_DLE_FRAME_INSTR_EXEC_ERROR);
  1115.     return(DW_DLV_ERROR);
  1116.     }
  1117.     
  1118.     if (register_num != NULL)
  1119.         *register_num = fde_table.fr_reg[table_column].ru_register;
  1120.     if (offset != NULL)
  1121.         *offset = fde_table.fr_reg[table_column].ru_offset;
  1122.     if (row_pc != NULL) 
  1123.     *row_pc = fde_table.fr_loc;
  1124.  
  1125.     *offset_relevant =  (fde_table.fr_reg[table_column].ru_is_off);
  1126.     return DW_DLV_OK;
  1127. }
  1128.  
  1129.  
  1130. int
  1131. dwarf_get_fde_n (
  1132.     Dwarf_Fde       *fde_data,
  1133.     Dwarf_Unsigned  fde_index,
  1134.     Dwarf_Fde      *returned_fde,
  1135.     Dwarf_Error     *error
  1136. )
  1137. {
  1138.     Dwarf_Debug     dbg;
  1139.  
  1140.     if (fde_data == NULL) {
  1141.     _dwarf_error(NULL,error,DW_DLE_FDE_PTR_NULL); 
  1142.     return(DW_DLV_ERROR);
  1143.     }
  1144.     
  1145.     if (*fde_data == NULL) {
  1146.     _dwarf_error(NULL,error,DW_DLE_FDE_NULL);
  1147.     return(DW_DLV_ERROR);
  1148.     }
  1149.  
  1150.     dbg = (*fde_data)->fd_dbg;
  1151.     if (dbg == NULL) {
  1152.     _dwarf_error(NULL,error,DW_DLE_FDE_DBG_NULL);
  1153.     return(DW_DLV_ERROR);
  1154.     }
  1155.  
  1156.     if (fde_index >= dbg->de_fde_count) {
  1157.         return(DW_DLV_NO_ENTRY);
  1158.     }
  1159.     *returned_fde =     (*(fde_data + fde_index));
  1160.     return DW_DLV_OK;
  1161. }
  1162.  
  1163.  
  1164. /* 
  1165.     Lopc and hipc are extensions to the interface to 
  1166.     return the range of addresses that are described
  1167.     by the returned fde.
  1168. */
  1169. int
  1170. dwarf_get_fde_at_pc (
  1171.     Dwarf_Fde       *fde_data,
  1172.     Dwarf_Addr      pc_of_interest,
  1173.     Dwarf_Fde     * returned_fde,
  1174.     Dwarf_Addr        *lopc,
  1175.     Dwarf_Addr        *hipc,
  1176.     Dwarf_Error     *error
  1177. )
  1178. {
  1179.     Dwarf_Debug     dbg;
  1180.     Dwarf_Sword     i;
  1181.     Dwarf_Fde       fde;
  1182.  
  1183.     if (fde_data == NULL) {
  1184.     _dwarf_error(NULL,error,DW_DLE_FDE_PTR_NULL);
  1185.     return(DW_DLV_ERROR);
  1186.     }
  1187.     
  1188.     if (*fde_data == NULL) {
  1189.     _dwarf_error(NULL,error,DW_DLE_FDE_NULL);
  1190.     return(DW_DLV_ERROR);
  1191.     }
  1192.  
  1193.     dbg = (*fde_data)->fd_dbg;
  1194.     if (dbg == NULL) {
  1195.     _dwarf_error(NULL,error,DW_DLE_FDE_DBG_NULL);
  1196.     return(DW_DLV_ERROR);
  1197.     }
  1198.  
  1199.     for (i = 0; i < dbg->de_fde_count; i++) {
  1200.         fde = *(fde_data + i);
  1201.         if (pc_of_interest >= fde->fd_initial_location &&
  1202.             pc_of_interest < fde->fd_initial_location+fde->fd_address_range)
  1203.             break;
  1204.     }
  1205.     if (i < dbg->de_fde_count) {
  1206.     if (lopc != NULL) *lopc = fde->fd_initial_location;
  1207.     if (hipc != NULL) *hipc = fde->fd_initial_location +
  1208.         fde->fd_address_range - 1;
  1209.     *returned_fde = fde;
  1210.         return(DW_DLV_OK);
  1211.     }
  1212.  
  1213.     return(DW_DLV_NO_ENTRY);
  1214. }
  1215.  
  1216.  
  1217. int
  1218. dwarf_expand_frame_instructions (
  1219.     Dwarf_Debug         dbg,
  1220.     Dwarf_Ptr           instruction,
  1221.     Dwarf_Unsigned      i_length,
  1222.     Dwarf_Frame_Op      **returned_op_list,
  1223.     Dwarf_Signed     *  returned_op_count,
  1224.     Dwarf_Error         *error
  1225. )
  1226. {
  1227.     Dwarf_Sword         instr_count;
  1228.  
  1229.     if (dbg == 0) {
  1230.     _dwarf_error(NULL,error,DW_DLE_DBG_NULL);
  1231.     return(DW_DLV_ERROR);
  1232.     }
  1233.  
  1234.     if (returned_op_list == 0 || returned_op_count == 0) {
  1235.     _dwarf_error(dbg,error,DW_DLE_RET_OP_LIST_NULL);
  1236.     return(DW_DLV_ERROR);
  1237.     }
  1238.  
  1239.     instr_count = _dwarf_exec_frame_instr (true, returned_op_list,
  1240.         false, NULL, 0,
  1241.         instruction, (Dwarf_Ptr)((Dwarf_Unsigned)instruction + i_length),
  1242.         NULL, NULL, dbg);
  1243.     if (instr_count < 0) {
  1244.     _dwarf_error(dbg,error,DW_DLE_FRAME_INSTR_EXEC_ERROR);
  1245.     return(DW_DLV_ERROR);
  1246.     }
  1247.     
  1248.     *returned_op_count = instr_count;
  1249.     return DW_DLV_OK;
  1250. }
  1251.  
  1252.  
  1253.  
  1254. /*
  1255.     Used by rqs.  Returns DW_DLV_OK if returns the arrays.
  1256.     Returns DW_DLV_NO_ENTRY if no section. ?? (How do I tell?)
  1257.     Returns DW_DLV_ERROR if there is an error.
  1258.  
  1259. */
  1260. int
  1261. _dwarf_frame_address_offsets(Dwarf_Debug dbg,Dwarf_Addr  **addrlist,
  1262.     Dwarf_Off  **offsetlist,Dwarf_Signed *returncount,Dwarf_Error *err)
  1263. {
  1264.   int retval = DW_DLV_OK;
  1265.   Dwarf_Signed res;
  1266.   Dwarf_Cie *cie_data;
  1267.   Dwarf_Signed cie_count;
  1268.   Dwarf_Fde *fde_data;
  1269.   Dwarf_Signed fde_count;
  1270.   Dwarf_Signed i;
  1271.   Dwarf_Frame_Op *frame_inst;
  1272.   Dwarf_Fde fdep;
  1273.   Dwarf_Cie ciep;
  1274.   Dwarf_Chain curr_chain = 0;
  1275.   Dwarf_Chain head_chain = 0;
  1276.   Dwarf_Chain prev_chain = 0;
  1277.   Dwarf_Arange arange;
  1278.   Dwarf_Unsigned arange_count = 0;
  1279.   Dwarf_Addr *arange_addrs = 0;
  1280.   Dwarf_Off  *arange_offsets = 0;
  1281.  
  1282.   res = dwarf_get_fde_list(dbg,&cie_data,&cie_count,
  1283.     &fde_data,&fde_count,err);
  1284.   if(res != DW_DLV_OK) {
  1285.     return res;
  1286.   }
  1287.   for(i = 0;  i < cie_count;  i++) {
  1288.     Dwarf_Off instoff =  0;
  1289.     Dwarf_Signed initial_instructions_length = 0;
  1290.     Dwarf_Small * instr_end = 0;
  1291.     Dwarf_Sword icount = 0;
  1292.     int j;
  1293.     ciep = cie_data[i];
  1294.     instoff = 
  1295.         ciep->ci_cie_instr_start - dbg->de_debug_frame;
  1296.     initial_instructions_length = ciep->ci_length +
  1297.             dbg->de_length_size -
  1298.             (ciep->ci_cie_instr_start - ciep->ci_cie_start);
  1299.     instr_end = ciep->ci_cie_instr_start +
  1300.         initial_instructions_length;
  1301.     icount = _dwarf_exec_frame_instr(/*make_instr*/true,
  1302.         &frame_inst,
  1303.         /* search_pc=*/false,
  1304.         /*search_pc_val=*/0,
  1305.         /*location*/ 0,
  1306.          ciep->ci_cie_instr_start,
  1307.          instr_end,
  1308.          /* Dwarf_frame=*/0,
  1309.          /* cie=*/0,
  1310.          dbg);
  1311.     if(icount < 0) {
  1312.         _dwarf_error(dbg,err,DW_DLE_FRAME_INSTR_EXEC_ERROR);
  1313.         return(DW_DLV_ERROR);
  1314.     }
  1315.          
  1316.     for(j = 0; j < icount; ++j) {
  1317.     if(frame_inst[i].fp_base_op == 0 &&
  1318.         frame_inst[i].fp_extended_op == 1)  {
  1319.       /* is DW_CFA_set_loc */
  1320.       Dwarf_Addr add = (Dwarf_Addr)frame_inst[i].fp_offset;
  1321.       Dwarf_Off off = frame_inst[i].fp_instr_offset + instoff;
  1322.  
  1323.                 arange = (Dwarf_Arange)
  1324.                     _dwarf_get_alloc(dbg, DW_DLA_ARANGE, 1);
  1325.                 if (arange == NULL) {
  1326.                     _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
  1327.                     return(DW_DLV_ERROR);
  1328.                 }
  1329.                 arange->ar_address = add;
  1330.                 arange->ar_info_offset = off;
  1331.                 arange_count++;
  1332.                 curr_chain = (Dwarf_Chain)
  1333.                     _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
  1334.                 if (curr_chain == NULL) {
  1335.                     _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
  1336.                     return(DW_DLV_ERROR);
  1337.                 }
  1338.                 curr_chain->ch_item = arange;
  1339.                 if (head_chain == NULL)
  1340.                     head_chain = prev_chain = curr_chain;
  1341.                 else {
  1342.                     prev_chain->ch_next = curr_chain;
  1343.                     prev_chain = curr_chain;
  1344.                 }
  1345.     }
  1346.     }
  1347.     dwarf_dealloc(dbg,frame_inst,DW_DLA_FRAME_BLOCK);
  1348.     
  1349.   }
  1350.   for(i = 0;  i < fde_count; i++) {
  1351.      Dwarf_Small *instr_end = 0;
  1352.      Dwarf_Sword icount = 0;
  1353.      Dwarf_Signed instructions_length = 0;
  1354.      Dwarf_Off instoff = 0; 
  1355.      Dwarf_Off off = 0;
  1356.      Dwarf_Addr addr = 0;
  1357.      int j;
  1358.  
  1359.      fdep = fde_data[i];
  1360.      off = fdep->fd_initial_loc_pos - dbg->de_debug_frame;
  1361.      addr = fdep->fd_initial_location;
  1362.                arange = (Dwarf_Arange)
  1363.                     _dwarf_get_alloc(dbg, DW_DLA_ARANGE, 1);
  1364.                 if (arange == NULL) {
  1365.                     _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
  1366.                     return(DW_DLV_ERROR);
  1367.                 }
  1368.                 arange->ar_address = addr;
  1369.                 arange->ar_info_offset = off;
  1370.                 arange_count++;
  1371.                 curr_chain = (Dwarf_Chain)
  1372.                     _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
  1373.                 if (curr_chain == NULL) {
  1374.                     _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
  1375.                     return(DW_DLV_ERROR);
  1376.                 }
  1377.                 curr_chain->ch_item = arange;
  1378.                 if (head_chain == NULL)
  1379.                     head_chain = prev_chain = curr_chain;
  1380.                 else {
  1381.                     prev_chain->ch_next = curr_chain;
  1382.                     prev_chain = curr_chain;
  1383.                 }
  1384.  
  1385.  
  1386.      instoff = fdep->fd_fde_instr_start - dbg->de_debug_frame;
  1387.      instructions_length = fdep->fd_length +
  1388.             dbg->de_length_size -
  1389.             (fdep->fd_fde_instr_start - fdep->fd_fde_start);
  1390.      instr_end = fdep->fd_fde_instr_start +
  1391.         instructions_length;
  1392.      icount = _dwarf_exec_frame_instr(/*make_instr*/true,
  1393.         &frame_inst,
  1394.         /*search_pc=*/false,
  1395.         /*search_pc_val=*/0,
  1396.         /*location*/ 0,
  1397.          fdep->fd_fde_instr_start,
  1398.          instr_end,
  1399.          /* Dwarf_frame=*/0,
  1400.          /* cie=*/0,
  1401.          dbg);
  1402.     if(icount < 0) {
  1403.         _dwarf_error(dbg,err,DW_DLE_FRAME_INSTR_EXEC_ERROR);
  1404.         return(DW_DLV_ERROR);
  1405.     }
  1406.          
  1407.     for(j = 0; j < icount; ++j) {
  1408.     if(frame_inst[i].fp_base_op == 0 &&
  1409.         frame_inst[i].fp_extended_op == 1)  {
  1410.       /* is DW_CFA_set_loc */
  1411.       Dwarf_Addr add = (Dwarf_Addr)frame_inst[i].fp_offset;
  1412.       Dwarf_Off off = frame_inst[i].fp_instr_offset + instoff;
  1413.                arange = (Dwarf_Arange)
  1414.                     _dwarf_get_alloc(dbg, DW_DLA_ARANGE, 1);
  1415.                 if (arange == NULL) {
  1416.                     _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
  1417.                     return(DW_DLV_ERROR);
  1418.                 }
  1419.                 arange->ar_address = add;
  1420.                 arange->ar_info_offset = off;
  1421.                 arange_count++;
  1422.                 curr_chain = (Dwarf_Chain)
  1423.                     _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
  1424.                 if (curr_chain == NULL) {
  1425.                     _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
  1426.                     return(DW_DLV_ERROR);
  1427.                 }
  1428.                 curr_chain->ch_item = arange;
  1429.                 if (head_chain == NULL)
  1430.                     head_chain = prev_chain = curr_chain;
  1431.                 else {
  1432.                     prev_chain->ch_next = curr_chain;
  1433.                     prev_chain = curr_chain;
  1434.                 }
  1435.  
  1436.     }
  1437.     }
  1438.     dwarf_dealloc(dbg,frame_inst,DW_DLA_FRAME_BLOCK);
  1439.  
  1440.   }
  1441.   dwarf_dealloc(dbg,fde_data,DW_DLA_LIST);
  1442.   dwarf_dealloc(dbg,cie_data,DW_DLA_LIST);
  1443.   arange_addrs = (Dwarf_Addr *)
  1444.         _dwarf_get_alloc(dbg, DW_DLA_ADDR, arange_count);
  1445.   if (arange_addrs == NULL) {
  1446.         _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
  1447.         return(DW_DLV_ERROR);
  1448.   }
  1449.   arange_offsets = (Dwarf_Off *)
  1450.         _dwarf_get_alloc(dbg, DW_DLA_ADDR, arange_count);
  1451.   if (arange_offsets == NULL) {
  1452.         _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
  1453.         return(DW_DLV_ERROR);
  1454.   }
  1455.  
  1456.   curr_chain = head_chain;
  1457.   for (i = 0; i < arange_count; i++) {
  1458.         Dwarf_Arange   ar = curr_chain->ch_item;
  1459.         arange_addrs[i] = ar->ar_address;
  1460.         arange_offsets[i] = ar->ar_info_offset;
  1461.         prev_chain = curr_chain;
  1462.         curr_chain = curr_chain->ch_next;
  1463.         dwarf_dealloc(dbg, ar, DW_DLA_ARANGE);
  1464.         dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN);
  1465.   }
  1466.   *returncount = arange_count;
  1467.   *offsetlist = arange_offsets;
  1468.   *addrlist = arange_addrs;
  1469.   return retval;
  1470. }
  1471.